package cz.muni.fi.pa165.dao;

import cz.muni.fi.pa165.entity.Months;
import cz.muni.fi.pa165.entity.Mushroom;
import cz.muni.fi.pa165.entity.MushroomType;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author Marek Tuhársky
 */
@Stateless
public class MushroomDAO implements MushroomDaoLocal {

    @PersistenceContext
    private EntityManager em;

    @Override
    public void createMushroom(Mushroom mushroom) {
        if (mushroom == null) {
            throw new IllegalArgumentException("Argument can not be null");
        }

        if (mushroom.getId() != null) {
            throw new IllegalArgumentException("Mushroom's id has already been set");
        }

        em.persist(mushroom);
    }

    @Override
    public Mushroom getMushroom(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("Argument can not be null");
        }
        if (id.longValue() < 0) {
            throw new IllegalArgumentException("Id can not be negative");
        }
        Mushroom mushroom;
        mushroom = em.find(Mushroom.class, id);
        return mushroom;


    }

    @Override
    public void updateMushroom(Mushroom mushroom) {
        if (mushroom == null) {
            throw new IllegalArgumentException("Argument can not be null");
        }
        Mushroom m = em.find(Mushroom.class, mushroom.getId());
        m.setName(mushroom.getName());
        m.setOccurenceFrom(mushroom.getOccurenceFrom());
        m.setOccurenceTo(mushroom.getOccurenceTo());
        m.setType(mushroom.getType());

    }

    @Override
    public void removeMushroom(Mushroom mushroom) {
        if (mushroom == null) {
            throw new IllegalArgumentException("Argument can not be null");
        }

        if (mushroom.getId() == null) {
            throw new IllegalArgumentException("Id can not be null in delete function, argument is not in database");
        }
        Mushroom m = em.find(Mushroom.class, mushroom.getId());
        em.remove(m);

    }

    @Override
    public List<Mushroom> findAllMushrooms() {
        List<Mushroom> list = null;


        Query query = em.createQuery("SELECT m FROM cz.muni.fi.pa165.entity.Mushroom m");
        list = (List<Mushroom>) query.getResultList();



        return list;
    }

    @Override
    public Mushroom findMushroomsByName(String name) {
        if (name == null || name.isEmpty()) {
            throw new IllegalArgumentException("Argument can not be null or empty");
        }

        Mushroom result = null;

        Query q = em.createQuery("SELECT m FROM cz.muni.fi.pa165.entity.Mushroom m"
                + " where m.name like :name").setParameter("name", name);

        result = (Mushroom) q.getSingleResult();


        return result;
    }

    @Override
    public List<Mushroom> findMushroomsByType(MushroomType type) {
        if (type == null) {
            throw new IllegalArgumentException("Argument can not be null");
        }

        List<Mushroom> list = null;

        Query query = em.createQuery("SELECT m FROM cz.muni.fi.pa165.entity.Mushroom m"
                + " WHERE m.type = :type");
        query.setParameter("type", type);
        list = (List<Mushroom>) query.getResultList();


        return list;
    }

    @Override
    public List<Mushroom> findMushroomsByOccurence(Months from, Months to) {
        if (from == null || to == null) {
            throw new IllegalArgumentException("Argument can not be null");
        }

        if (from.ordinal() > to.ordinal()) {
            throw new IllegalArgumentException("Argument from cannot have bigger value than to");
        }

        List<Mushroom> list = null;

        Query query = em.createQuery("SELECT m FROM cz.muni.fi.pa165.entity.Mushroom m"
                + " WHERE m.occurenceFrom >= :from AND m.occurenceTo <= :to");
        query.setParameter("from", from);
        query.setParameter("to", to);
        list = (List<Mushroom>) query.getResultList();


        return list;
    }
}
